package com.lookme.lmtool.controller;

import com.lookme.core.javafx.FxApp;
import com.lookme.lmtool.CaptchaCrackerMain;
import com.lookme.lmtool.model.Env;
import com.lookme.lmtool.model.ItemInfo;
import com.lookme.lmtool.model.ProjectInfo;
import com.lookme.lmtool.utils.EnvUtils;
import com.lookme.lmtool.utils.ToolUtils;
import com.lookme.lmtool.view.RootLayoutView;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;

public class MainController extends RootLayoutView {


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        loadProject();
        initView();
        initEvent();
    }

    private void loadProject() {
        if(StringUtils.isNotEmpty(Env.getInstance().getLastOpenProject())){
            //加载最后一次打开的工程
            loadProject(Env.getInstance().getLastOpenProject());
        }else{
            ItemInfo itemInfo=new ItemInfo("default","未命名项目");

            ProjectInfo projectInfo=new ProjectInfo();
            projectInfo.addItem(itemInfo);
            Env.getInstance().setProjectInfo(projectInfo);
            FxApp.primaryStage.setTitle(CaptchaCrackerMain.TITLE+" - "+"未保存的工程");
            loadProjectItemLayout(itemInfo);
        }
        if(Env.getInstance().getHistoryProjects().size()>0){
            menuHistorySeparator.setVisible(true);
            for(String path:Env.getInstance().getHistoryProjects()){
                MenuItem menuHistory=new MenuItem(path);
                menuHistory.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                        alert.setTitle("确认保存");
                        alert.setHeaderText("打开工程前是否保存当前工程？");
                        alert.setContentText("");
                        Optional result = alert.showAndWait();
                        if (result.get() == ButtonType.OK) {
                            handlerSaveProject(event);
                        }
                        loadProject(((MenuItem)event.getSource()).getText());
                    }
                });
                menuProject.getItems().add(4,menuHistory);
            }
        }else{
            menuHistorySeparator.setVisible(false);
        }

    }


    private void initView() {
        btnDelItem.disableProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isNull());
        menuDelItem.disableProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isNull());
        menuRenameItem.disableProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isNull());

        menuNewProject.setGraphic(ToolUtils.getButtonGraphics("/images/new_project.png"));
        menuOpenProject.setGraphic(ToolUtils.getButtonGraphics("/images/open.png"));
        menuSaveProject.setGraphic(ToolUtils.getButtonGraphics("/images/save.png"));
        menuAddItem.setGraphic(ToolUtils.getButtonGraphics("/images/new_item.png"));
        menuDelItem.setGraphic(ToolUtils.getButtonGraphics("/images/delete.png"));
        menuRenameItem.setGraphic(ToolUtils.getButtonGraphics("/images/rename.png"));
        mennuExportItemLib.setGraphic(ToolUtils.getButtonGraphics("/images/export.png"));
        btnDelItem.setGraphic(ToolUtils.getButtonGraphics("/images/delete2.png"));
        btnNewItem.setGraphic(ToolUtils.getButtonGraphics("/images/new_item2.png"));
        menuExportProjectLib.setGraphic(ToolUtils.getButtonGraphics("/images/export.png"));
        menuExit.setGraphic(ToolUtils.getButtonGraphics("/images/exit.png"));
    }

    public void initEvent() {
        tabPane.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                Object userData=tabPane.getSelectionModel().getSelectedItem().getUserData();
                if (event.getClickCount() == 2&&userData!=null) {
                    if(userData instanceof CaptchaCrackerController) {
                        String text = tabPane.getSelectionModel().getSelectedItem().getText();
                        if (event.getTarget() instanceof Text && ((Text) event.getTarget()).getText().equals(text)) {
                            handlerRenameItem(null);
                        }
                    }
                }
            }
        });
        tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                Env.getInstance().getProjectInfo().setSelectTabIndex(newValue.intValue());
            }
        });
    }

    @FXML
    void handlerNewItem(ActionEvent event) {
        handleNewProjectItem();
    }

    @FXML
    void handlerDelItem(Event event) {
        Alert closeConfirmation = new Alert(
                Alert.AlertType.CONFIRMATION,
                "是否关闭【"+tabPane.getSelectionModel().getSelectedItem().getText()+"】该项目?"
        );
        closeConfirmation.setGraphic(ToolUtils.getButtonGraphics("/images/ocr.png"));
        Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(
                ButtonType.OK
        );
        exitButton.setText("关闭");
        closeConfirmation.setHeaderText("确定关闭？");
        closeConfirmation.initModality(Modality.APPLICATION_MODAL);
        closeConfirmation.initOwner(FxApp.primaryStage);

        closeConfirmation.setX(FxApp.primaryStage.getX() + FxApp.primaryStage.getWidth() / 2 - closeConfirmation.getWidth() / 2);
        closeConfirmation.setY(FxApp.primaryStage.getY() + FxApp.primaryStage.getHeight() / 2 - closeConfirmation.getHeight() / 2);

        Optional<ButtonType> closeResponse = closeConfirmation.showAndWait();
        if (!ButtonType.OK.equals(closeResponse.get())) {
            event.consume();
        }else{
            if(event!=null) {
                CaptchaCrackerController controller=(CaptchaCrackerController) tabPane.getSelectionModel().getSelectedItem().getUserData();
                Env.getInstance().getProjectInfo().getItemInfoList().remove(controller.getItemInfo());
                controller.destroy();
                tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());

            }
        }
    }

    @FXML
    void handlerRenameItem(ActionEvent event) {
        Tab tab=tabPane.getSelectionModel().getSelectedItem();
        Object userData=tab.getUserData();
        String text = tab.getText();
        ItemInfo itemInfo=((CaptchaCrackerController) userData).getItemInfo();
        showEditItemDialog(itemInfo);
        tab.setText(itemInfo.getName());
    }

    @FXML
    void handlerExit(ActionEvent event) {
        if(StringUtils.isEmpty(Env.getInstance().getProjectInfo().getPath())) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("确认退出");
            alert.setHeaderText("退出前是否保存当前工程？");
            alert.setContentText("");
            Optional result = alert.showAndWait();
            if (result.get() == ButtonType.OK) {
                File file = ToolUtils.createFileChooser("保存工程").showSaveDialog(FxApp.primaryStage);
                try {
                    if (file != null) {
                        try {
                            if (StringUtils.isEmpty(Env.getInstance().getProjectInfo().getPath())) {
                                Env.getInstance().getProjectInfo().setPath(file.getAbsolutePath());
                            }
                        } catch (Exception e) {

                        }
                        Env.getInstance().setInitDirectory(file.getParent());
                    }
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                }
            }else{
                System.exit(0);
            }
        }
        EnvUtils.saveProject(Env.getInstance().getProjectInfo());
        System.exit(0);
    }

    @FXML
    void handlerNewProject(ActionEvent event) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setTitle("确认保存");
        alert.setHeaderText("新建工程前是否保存当前工程？");
        alert.setContentText("");
        Optional result = alert.showAndWait();
        if (result.get() == ButtonType.OK) {
            handlerSaveProject(event);
        }
        tabPane.getTabs().clear();
        ItemInfo itemInfo=new ItemInfo("default","未命名项目");
        ProjectInfo projectInfo=new ProjectInfo();
        projectInfo.addItem(itemInfo);
        Env.getInstance().setProjectInfo(projectInfo);
        FxApp.primaryStage.setTitle(CaptchaCrackerMain.TITLE+" - "+"未保存的工程");
        loadProjectItemLayout(itemInfo);
    }
    private void loadProject(String filePath){
        tabPane.getTabs().clear();
        try {
            ProjectInfo projectInfo= EnvUtils.loadProject(filePath);
            FxApp.primaryStage.setTitle(CaptchaCrackerMain.TITLE+" - "+filePath);
            Env.getInstance().setProjectInfo(projectInfo);
            for(ItemInfo itemInfo:projectInfo.getItemInfoList()){
                loadProjectItemLayout(itemInfo);
            }
            tabPane.getSelectionModel().select(projectInfo.getSelectTabIndex());
        } catch (Exception e) {

        }
    }
    @FXML
    void handlerOpenProject(ActionEvent event) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setTitle("确认保存");
        alert.setHeaderText("打开工程前是否保存当前工程？");
        alert.setContentText("");
        Optional result = alert.showAndWait();
        if (result.get() == ButtonType.OK) {
            handlerSaveProject(event);
        }
        File file = ToolUtils.createFileChooser("打开工程").showOpenDialog(FxApp.primaryStage);
        try {
            if (file != null) {
                loadProject(file.getAbsolutePath());
                Env.getInstance().setInitDirectory(file.getParent());
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
    @FXML
    void handlerSaveProject(ActionEvent event) {
        if(StringUtils.isEmpty(Env.getInstance().getProjectInfo().getPath())) {
            File file = ToolUtils.createFileChooser("保存工程").showSaveDialog(FxApp.primaryStage);
            try {
                if (file != null) {
                    try {
                        if (StringUtils.isEmpty(Env.getInstance().getProjectInfo().getPath())) {
                            Env.getInstance().getProjectInfo().setPath(file.getAbsolutePath());
                        }
                    } catch (Exception e) {

                    }
                    Env.getInstance().setInitDirectory(file.getParent());
                }
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            }
        }
        EnvUtils.saveProject(Env.getInstance().getProjectInfo());
    }


    private Optional<ItemInfo> showEditItemDialog(ItemInfo itemInfo){
        Dialog<ItemInfo> dialog = new Dialog<>();
        Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
        stage.getIcons().add(new Image("/images/ocr.png"));
        dialog.getDialogPane().setGraphic(ToolUtils.getButtonGraphics("/images/ocr.png"));
        dialog.setTitle("请输入项目名称");
        dialog.setHeaderText("请输入项目名称");
// 设置头部图片
        dialog.setGraphic(ToolUtils.getButtonGraphics("/images/ocr.png"));

        ButtonType btnApply = new ButtonType("确定", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(btnApply, ButtonType.CANCEL);

        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 20, 20, 20));

        TextField txtItemId = new TextField();
        txtItemId.setPrefWidth(300);
        txtItemId.setPromptText("请输入项目ID，用于识别时调用使用");
        TextField txtItemName = new TextField();
        txtItemName.setPrefWidth(300);
        txtItemName.setPromptText("请输入项目名称");

        if(itemInfo!=null){
            txtItemId.setText(itemInfo.getId());
            txtItemName.setText(itemInfo.getName());
        }else{
            itemInfo=new ItemInfo();
        }

        grid.add(new Label("项目ID:"), 0, 0);
        grid.add(txtItemId, 1, 0);
        grid.add(new Label("项目名称:"), 0, 1);
        grid.add(txtItemName, 1, 1);
        Node loginButton = dialog.getDialogPane().lookupButton(btnApply);
        loginButton.setDisable(true);

        txtItemId.textProperty().addListener((observable, oldValue, newValue) -> {
            loginButton.setDisable(newValue.trim().isEmpty() || txtItemName.getText().trim().isEmpty());
        });

        txtItemName.textProperty().addListener((observable, oldValue, newValue) -> {
            loginButton.setDisable(newValue.trim().isEmpty() || txtItemId.getText().trim().isEmpty());
        });
        dialog.getDialogPane().setContent(grid);
        // 默认光标在用户名上
        Platform.runLater(() -> txtItemId.requestFocus());

        final ItemInfo editItem=itemInfo;
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == btnApply) {
                editItem.setId(txtItemId.getText());
                editItem.setName(txtItemName.getText());
                return editItem;
            }
            return null;
        });
        Optional<ItemInfo> result = dialog.showAndWait();
        return result;
    }

    @FXML
    private ItemInfo handleNewProjectItem() {
        ItemInfo itemInfo=null;
        try {
            Optional<ItemInfo> result=showEditItemDialog(itemInfo);
            if(result.isPresent()){
                itemInfo=result.get();
                loadProjectItemLayout(itemInfo);
                Env.getInstance().getProjectInfo().getItemInfoList().add(itemInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return itemInfo;
    }


    public void loadProjectItemLayout(ItemInfo itemInfo) {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader();
            fxmlLoader.setLocation(CaptchaCrackerController.class.getResource("/fxml/com/lookme/lmtool/CaptchaCracker.fxml"));
            fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
            Parent root = fxmlLoader.load();
            CaptchaCrackerController controller = fxmlLoader.getController();

            controller.init(this,itemInfo);
            Tab tab = new Tab();
            tab.setText(itemInfo.getName());
            tab.setClosable(true);
            tab.setContent(root);
            tab.setUserData(controller);
            tab.setOnCloseRequest(new EventHandler<Event>() {
                @Override
                public void handle(Event event) {
                    handlerDelItem(event);
                }
            });
            tab.setGraphic(ToolUtils.getButtonGraphics("/images/ocr.png"));
            int index=tabPane.getTabs().size();

            tabPane.getTabs().add(index,tab);
            tabPane.getSelectionModel().select(tab);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
